package client;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Label;

import javax.swing.*;

import java.awt.Font;

import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.border.EmptyBorder;

import com.google.gson.Gson;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

import org.java_websocket.WebSocketImpl;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_10;
import org.java_websocket.drafts.Draft_17;
import org.java_websocket.drafts.Draft_75;
import org.java_websocket.drafts.Draft_76;
import org.java_websocket.handshake.ServerHandshake;

import java.awt.FlowLayout;

public class clientTwo_2 extends JFrame implements ActionListener {

	private JPanel contentPane;
	private static int serverPort = 9999;	//port
	private static InetAddress serverIp ;	//IP
	static Socket clientSocket;				// 客戶端socket
	static String tmp;						// 暫存文字訊息
	private static JTextField nameField;	//使用者
	private static JTextField messageField;//訊息輸入入
	private static JTextArea txtMessage;
	private WebSocketClient cc;
	private final JTextField uriField;
	private final JComboBox draft;
	private JButton btnSend;
	private JButton btnCloseConn;
	private JButton btnConnect;
	
	public static void main(String[] args) {
		String location;
		if( args.length != 0 ) {
			location = args[ 0 ];
			System.out.println( "Default server url specified: \'" + location + "\'" );
		} else {
			location = "ws://localhost:9999";
			System.out.println( "Default server url not specified: defaulting to \'" + location + "\'" );
		}
		new clientTwo_2( location );

	}

	/**
	 * Create the frame.
	 */
	public clientTwo_2(String defaultlocation) {
		
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 500, 550);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));
		
		JPanel panel = new JPanel();
		contentPane.add(panel,BorderLayout.NORTH);
		panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
		
		btnConnect = new JButton("連線");
		btnConnect.setFont(new Font("新細明體", Font.PLAIN, 18));
		btnConnect.addActionListener( this );
		panel.add(btnConnect);
		
		btnCloseConn = new JButton("斷線");
		btnCloseConn.setFont(new Font("新細明體", Font.PLAIN, 18));
		btnCloseConn.addActionListener( this );
		panel.add(btnCloseConn);

		uriField = new JTextField();
		uriField.setFont(new Font("新細明體", Font.PLAIN, 18));
		uriField.setText( defaultlocation );
		panel.add( uriField );
		
		Draft[] drafts = { new Draft_17(), new Draft_10(), new Draft_76(), new Draft_75() };
		draft = new JComboBox( drafts );
		panel.add( draft );
		
		JScrollPane scrollPane = new JScrollPane();
		contentPane.add(scrollPane,BorderLayout.CENTER);
		
		txtMessage = new JTextArea();
		txtMessage.setFont(new Font("新細明體", Font.PLAIN, 18));
		txtMessage.setRows(15);
		scrollPane.setViewportView(txtMessage);
		
		JSplitPane splitPane = new JSplitPane();
		contentPane.add(splitPane,BorderLayout.SOUTH);
		
		JPanel panelDownLeft = new JPanel();
		panelDownLeft.setLayout(new BoxLayout(panelDownLeft, BoxLayout.X_AXIS));
		
		JLabel lblName = new JLabel("使用者");
		lblName.setFont(new Font("新細明體", Font.PLAIN, 18));
		panelDownLeft.add(lblName);
		
		nameField = new JTextField("JavaSwing");
		nameField.setFont(new Font("新細明體", Font.PLAIN, 18));
		nameField.setColumns(10);
		panelDownLeft.add(nameField);
		splitPane.setLeftComponent(panelDownLeft);
		
		JPanel panelDownRight = new JPanel();
		messageField = new JTextField();
		messageField.setText("my Swing Message");
		messageField.setFont(new Font("新細明體", Font.PLAIN, 18));
		nameField.setColumns(10);
		panelDownRight.setLayout(new BoxLayout(panelDownRight, BoxLayout.X_AXIS));
		panelDownRight.add(messageField);
		
		btnSend = new JButton("送出");
		btnSend.setFont(new Font("新細明體", Font.PLAIN, 18));
		panelDownRight.add(btnSend);
		btnSend.addActionListener( this );
		
		splitPane.setRightComponent(panelDownRight);
		
		
		addWindowListener( new java.awt.event.WindowAdapter() {
			@Override
			public void windowClosing( WindowEvent e ) {
				if( cc != null ) {
					cc.close();
				}
				dispose();
			}
		} );

		setLocationRelativeTo( null );
		setVisible( true );
	}
	
	public void actionPerformed( ActionEvent e ) {

		if( e.getSource() == btnSend ) {
			if( cc != null ) {
				SimpleDateFormat sdFormat = new SimpleDateFormat("a hh:mm:ss");
				Date today = new Date();	
				Message myMessage = new Message(nameField.getText(), messageField.getText(), sdFormat.format(today));
				Gson gson = new Gson();	
				String json = gson.toJson(myMessage);
				cc.send(json);
				
				//cc.send( messageField.getText() );
				messageField.setText("");
				messageField.requestFocus();
			}

		} else if( e.getSource() == btnConnect ) {
			try {
				// cc = new ChatClient(new URI(uriField.getText()), area, ( Draft ) draft.getSelectedItem() );
				cc = new WebSocketClient( new URI( uriField.getText() ), (Draft) draft.getSelectedItem() ) {

					@Override
					public void onMessage( String message ) {
						//先確認能不能轉JSON格式
						String myMsg;
						if(isJSONValid(message)){
							Gson gson = new Gson();
							Message inputMessage = gson.fromJson(message, Message.class);
							myMsg = inputMessage.getName()+":" + 
									inputMessage.getMsg()+"\t\t" +
									inputMessage.getTime() + "\n" ;
							txtMessage.append( myMsg );
							
						}else{
							//若不是，那就單純接收伺服器訊息
							txtMessage.append( "Server: " + message + "\n" );
						}
						
						txtMessage.setCaretPosition( txtMessage.getDocument().getLength() );
					}

					@Override
					public void onOpen( ServerHandshake handshake ) {
						txtMessage.append( "You are connected to ChatServer: " + getURI() + "\n" );
						txtMessage.setCaretPosition( txtMessage.getDocument().getLength() );
					}

					@Override
					public void onClose( int code, String reason, boolean remote ) {
						txtMessage.append( "You have been disconnected from: " + getURI() + "; Code: " + code + " " + reason + "\n" );
						txtMessage.setCaretPosition( txtMessage.getDocument().getLength() );
						btnConnect.setEnabled( true );
						uriField.setEditable( true );
						draft.setEditable( true );
						btnCloseConn.setEnabled( false );
					}

					@Override
					public void onError( Exception ex ) {
						txtMessage.append( "Exception occured ...\n" + ex + "\n" );
						txtMessage.setCaretPosition( txtMessage.getDocument().getLength() );
						ex.printStackTrace();
						btnConnect.setEnabled( true );
						uriField.setEditable( true );
						draft.setEditable( true );
						btnCloseConn.setEnabled( false );
					}
				};

				btnCloseConn.setEnabled( true );
				btnConnect.setEnabled( false );
				uriField.setEditable( false );
				draft.setEditable( false );
				cc.connect();
			} catch ( URISyntaxException ex ) {
				txtMessage.append( uriField.getText() + " is not a valid WebSocket URI\n" );
			}
		} else if( e.getSource() == btnCloseConn ) {
			cc.close();
		}
	}
	//確認是不是Message格式進來的資料
	public static boolean isJSONValid(String JSON_STRING) {
		Gson gson = new Gson();
	      try {
	          gson.fromJson(JSON_STRING, Message.class);
	          return true;
	      } catch(com.google.gson.JsonSyntaxException ex) { 
	          return false;
	      }
	  }
	
}
